package com.nolon.flange.fragment

import android.content.Context
import android.content.Intent
import android.os.Build
import android.os.Bundle
import android.os.StrictMode
import android.provider.MediaStore
import android.view.LayoutInflater
import android.view.View
import android.view.ViewGroup
import android.view.inputmethod.InputMethodManager
import androidx.appcompat.app.AlertDialog
import androidx.appcompat.app.AppCompatActivity
import androidx.fragment.app.Fragment
import androidx.lifecycle.ViewModelProvider
import androidx.preference.PreferenceManager
import androidx.recyclerview.widget.LinearLayoutManager
import com.nolon.flange.R
import com.nolon.flange.adapter.FileAdapter
import com.nolon.flange.databinding.FragmentFileBinding
import com.nolon.flange.extensions.toast
import com.nolon.flange.model.FileItem
import com.nolon.flange.tools.OpenFiles
import com.nolon.flange.viewmodel.ProjectViewModel
import java.io.File
import java.lang.reflect.Method


class FileFragment(private val parent: AppCompatActivity) : Fragment() {
    private var _binding: FragmentFileBinding? = null
    private val bd get() = _binding!!

    private val viewModel by lazy { ViewModelProvider(parent).get(ProjectViewModel::class.java) }

    private val fileAdapter by lazy { FileAdapter(onFileClicked, onMoreClicked) }

    override fun onCreateView(
        inflater: LayoutInflater,
        container: ViewGroup?,
        savedInstanceState: Bundle?
    ): View {
        _binding = FragmentFileBinding.inflate(inflater, container, false)
        return bd.root
    }

    override fun onViewCreated(view: View, savedInstanceState: Bundle?) {
        super.onViewCreated(view, savedInstanceState)

        initView()

        initData()
    }

    private fun initData() {
        viewModel.files.observe(viewLifecycleOwner) {
            fileAdapter.swapData(it)
        }
    }

    private val onFileClicked: (FileItem) -> Unit = {
        if (PreferenceManager.getDefaultSharedPreferences(requireContext())
                .getBoolean(getString(R.string.force_open_excel), false)
        ) {
            try {
                forceMode()
                val openFileIntent = OpenFiles.getExcelFileIntent(it.path)
                activity?.startActivity(openFileIntent)
            } catch (e: Exception) {
                e.printStackTrace()
            }
        } else {
            if (Build.VERSION.SDK_INT >= 24) {
                val intent = Intent(Intent.ACTION_VIEW).apply {
                    setFlags(Intent.FLAG_GRANT_READ_URI_PERMISSION)
                    addFlags(Intent.FLAG_GRANT_WRITE_URI_PERMISSION)
                    addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                    addCategory(Intent.CATEGORY_DEFAULT)
                    setDataAndType(it.uri, "application/vnd.ms-excel")
                }
                val chooser = Intent.createChooser(intent, "")
                try {
                    activity?.startActivity(chooser)
                } catch (e: Exception) {
                    toast(requireContext(), "打开失败，请通过文件管理器打开")
                    e.printStackTrace()
                }
            } else {
                val openFileIntent = OpenFiles.getExcelFileIntent(it.path)
                try {
                    activity?.startActivity(openFileIntent)
                } catch (e: Exception) {
                    e.printStackTrace()
                }
            }
        }
    }

    private val onMoreClicked: (FileItem) -> Unit = {
        val dialog = AlertDialog.Builder(this.requireContext())
        with(dialog) {
            setTitle("执行操作")
            setPositiveButton("删除") { _, _ ->
                val file = File(it.path)
                if (file.exists()) {
                    val where = MediaStore.MediaColumns.DATA + "=?"
                    val selectionArgs = arrayOf(file.absolutePath)
                    // Delete the entry from the media database. This will actually delete media files (images,
                    // audio, and video).
                    context.contentResolver.delete(
                        MediaStore.Files.getContentUri("external"),
                        where,
                        selectionArgs
                    )
                    viewModel.refreshFiles(requireContext())
                }
            }
            setNegativeButton("取消", null)
            show()
        }
    }


    private fun forceMode() {
        val m: Method =
            StrictMode::class.java.getMethod("disableDeathOnFileUriExposure")
        m.invoke(null)
    }

    private fun initView() {
        bd.recyclerFiles.apply {
            adapter = fileAdapter
            layoutManager =
                LinearLayoutManager(this.context, LinearLayoutManager.VERTICAL, false)
            addItemDecoration(
                com.nolon.flange.view.DividerItemDecoration(
                    this.context,
                    showtopbottomdividers = true,
                    show = true
                )
            )
        }
        bd.swipeRefresh.apply {
            viewModel.refreshFiles(this.context)
            setOnRefreshListener {
                isRefreshing = true
                viewModel.refreshFiles(this.context)
                isRefreshing = false
            }
        }
    }


    private fun closeKeyboard() {
        val view: View? = activity?.currentFocus
        if (view != null) {
            val imm: InputMethodManager =
                activity?.getSystemService(Context.INPUT_METHOD_SERVICE) as InputMethodManager
            imm.hideSoftInputFromWindow(view.windowToken, 0)
        }
    }

    private fun showInstruction() {
        val alertDialog = AlertDialog.Builder(requireContext())
        val instructionPage =
            LayoutInflater.from(requireContext()).inflate(R.layout.dialog_instruction, null)
        alertDialog.setView(instructionPage)
        val instructionDialog = alertDialog.create()
        instructionDialog.show()
    }

    override fun onDestroyView() {
        super.onDestroyView()
        //注意：Fragment 的存在时间比其视图长。请务必在 Fragment 的 onDestroyView() 方法中清除对绑定类实例的所有引用。
        _binding = null
    }

}